/*!
\copyright  Copyright (c) 2021 Qualcomm Technologies International, Ltd.\n
            All Rights Reserved.\n
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\brief      Qualcomm Debug over Charger Comms channel.
*/

#ifndef QCOM_DEBUG_CHANNEL_H_
#define QCOM_DEBUG_CHANNEL_H_

/*-----------------------------------------------------------------------------
------------------ INCLUDES ---------------------------------------------------
-----------------------------------------------------------------------------*/

#include <stdint.h>
#include <stdbool.h>
#include "ccp.h"

/* USB vendor unlock definitions */

#define USB_BMREQUESTTYPE_DEVICE         0x00
#define USB_BMREQUESTTYPE_VENDOR         0x40
#define USB_BMREQUESTTYPE_DEVICE_TO_HOST 0x80

#define USB_BREQUEST_UNLOCK_DEBUGGER     0x00
#define USB_BREQUEST_LOCK_DEBUGGER       0x01
#define USB_BREQUEST_UNLOCK_STATUS       0x02
#define USB_WVALUE_UNLOCK_DEBUGGER       0x0000
#define USB_WLENGTH_UNLOCK_DEBUGGER      16
#define USB_WLENGTH_LOCK_DEBUGGER        1
#define USB_WLENGTH_UNLOCK_STATUS        1

#define USB_WINDEX_LEFT_EARBUD           0x0001
#define USB_WINDEX_RIGHT_EARBUD          0x0002

#define USB_DEBUG_UNLOCK_STATUS_TIMEOUT_US (3 * 1000 * 1000)

/*-----------------------------------------------------------------------------
------------------ TYPE DEFINITIONS -------------------------------------------
-----------------------------------------------------------------------------*/

/**
 * The unlock status of a device as returned by the USB UNLOCK_STATUS vendor
 * request.
 */
typedef enum
{
    /** The interface is locked */
    USB_DEBUG_UNLOCK_STATUS_LOCKED   = 0,
    /** The interface is unlocked */
    USB_DEBUG_UNLOCK_STATUS_UNLOCKED = 1,
    /* The status could not be retrieved */
    USB_DEBUG_UNLOCK_STATUS_UNKNOWN  = 2
} USB_DEBUG_UNLOCK_STATUS;

/**
 * A structure representing a Qualcomm Debug over Charger Comms forwarding
 * transaction.
 *
 * This can be used for either:
 * - case comms -> USB
 * - USB -> case comms
 */
typedef struct
{
    /** The EARBUD to forward this data to*/
    uint8_t earbud;
    /** The number of octets to forward */
    uint16_t length;
    /** The data to forward */
    uint8_t *tx_data;
    /** Callback when the data has been successfully forwarded */
    void (*cb)(void);
} QCOM_DEBUG_CHANNEL_TRANSACTION;

/**
 * \brief A callback function for transmitting a vendor request response from
 * an earbud back to the USB host
 *
 * \param earbud The earbud this vendor request response is from.
 * \param data A pointer to the data that forms this response.
 * \param len The length of \a data in octets.
 */
typedef void (*tx_vendor_rsp_fn)(uint8_t earbud, uint8_t *data, uint16_t len);

/*-----------------------------------------------------------------------------
------------------ FUNCTIONS --------------------------------------------------
-----------------------------------------------------------------------------*/

/**
 * \brief Process a charger comms message which has arrived on the
 *        Qualcomm USB Debug channel
 *        The case is responsible for forwarding these to the Qualcomm USB
 *        Debug interface.
 * 
 * \param earbud The earbud which sent this message
 * \param msg_id The type of message that has arrived.
 * \param data A pointer to the data that forms this message.
 * \param len The length of \a data in octets.
 * \return None
 */
void qcom_debug_channel_rx(uint8_t earbud, uint8_t msg_id, uint8_t *data, uint16_t len);

/**
 * \brief Transmit a Qualcomm USB Debug channel data message to a specified earbud over
 *        charger comms.
 * 
 * \param earbud The earbud to send this message to.
 * \param data A pointer to the data that forms this message.
 * \param len The length of \a data in octets.
 * \return True if successful, false otherwise.
 */
bool qcom_debug_channel_data_tx(uint8_t earbud, uint8_t *data, uint16_t len);

/**
 * \brief Transmit a Qualcomm Debug channel message requesting a random token
 *        for unlocking the transport
 *
 * \param earbud The earbud to request the random key from
 * \param fn A callback for when the random token has been retrieved.
 */
void qcom_debug_channel_request_random_token(uint8_t earbud, tx_vendor_rsp_fn fn);

/**
 * \brief Transmit a Qualcomm Debug channel message containing an unlock key
 *        generated by the USB host.
 *
 * \param earbud The earbud to send this unlock message to.
 * \param data A pointer to the data that forms this message.
 * \param len The length of \a data in octets.
 */
void qcom_debug_channel_unlock_key_tx(uint8_t earbud, uint8_t *data, uint16_t len);

/**
 * \brief Transmit a Qualcomm Debug channel unlock status request to an earbud
 *
 * \param earbud The earbud to make the request to
 * \param fn A callback for when the status has been retrieved.
 */
void qcom_debug_channel_unlock_status_req(uint8_t earbud, tx_vendor_rsp_fn fn);

/**
 * \brief Transmit a Qualcomm Debug channel lock message to an earbud to
 * re-lock the interface.
 *
 * \param earbud The earbud to send the lock request to.
 */
void qcom_debug_channel_lock_req(uint8_t earbud);

/**
 * \brief The periodic function which drives the Qualcomm USB Debug channel.
 */
void qcom_debug_channel_periodic(void);

#endif /* QCOM_DEBUG_CHANNEL_H_ */
